/**
 * 邮箱校验工具函数 - TypeScript版本
 * 提供邮箱格式校验、批量校验、格式化、脱敏等功能
 * 支持直接复制粘贴使用，无需任何依赖
 * 每个函数都是独立的，可以单独复制使用
 */

// 类型定义
export interface EmailValidationResult {
  isValid: boolean;
  message: string;
  domain: string | null;
  localPart: string | null;
}

export interface BatchEmailValidationResult {
  isValid: boolean;
  message: string;
  validEmails: string[];
  invalidEmails: Array<{
    email: string;
    reason: string;
  }>;
  duplicateEmails: string[];
  totalCount: number;
  validCount: number;
  invalidCount: number;
  duplicateCount: number;
  emptyCount: number;
  exceededCount: number;
}

export interface EmailCountLimitResult {
  isValid: boolean;
  message: string;
  totalCount: number;
  exceededCount: number;
  insufficientCount: number;
}

export interface EmailPaginationResult {
  emails: string[];
  totalCount: number;
  pageSize: number;
  currentPage: number;
  totalPages: number;
  hasNext: boolean;
  hasPrev: boolean;
}

export interface EmailPaginationWithValidationResult extends EmailPaginationResult {
  validationResult: BatchEmailValidationResult;
}

export interface EmailFormatOptions {
  toLowerCase?: boolean;
  trim?: boolean;
}

export interface EmailMaskOptions {
  maskChar?: string;
  showFirst?: number;
  showLast?: number;
}

export interface BatchEmailValidationConfig {
  maxCount?: number;
  minCount?: number;
  checkUnique?: boolean;
  allowEmpty?: boolean;
  strictMode?: boolean;
  whitelist?: string[];
  blacklist?: string[];
  blockTemporary?: boolean;
}

// 常量定义
export const EMAIL_REGEX = {
  BASIC: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
  STRICT: /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
  RFC5322: /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
} as const;

export const TEMPORARY_EMAIL_DOMAINS = [
  '10minutemail.com', 'tempmail.org', 'guerrillamail.com', 'mailinator.com',
  'throwaway.email', 'temp-mail.org', 'getnada.com', 'maildrop.cc',
  'yopmail.com', 'sharklasers.com', 'guerrillamailblock.com'
] as const;

/**
 * 基础邮箱校验
 * @param {string} email - 邮箱地址
 * @returns {EmailValidationResult} 校验结果
 */
export function validateEmail(email: string): EmailValidationResult {
  if (!email || typeof email !== 'string') {
    return {
      isValid: false,
      message: '邮箱地址不能为空',
      domain: null,
      localPart: null
    };
  }

  const trimmedEmail = email.trim();
  
  if (trimmedEmail === '') {
    return {
      isValid: false,
      message: '邮箱地址不能为空',
      domain: null,
      localPart: null
    };
  }

  if (!EMAIL_REGEX.BASIC.test(trimmedEmail)) {
    return {
      isValid: false,
      message: '邮箱格式不正确',
      domain: null,
      localPart: null
    };
  }

  const [localPart, domain] = trimmedEmail.split('@');
  
  return {
    isValid: true,
    message: '邮箱格式正确',
    domain: domain,
    localPart: localPart
  };
}

/**
 * 严格邮箱校验
 * @param {string} email - 邮箱地址
 * @returns {EmailValidationResult} 校验结果
 */
export function validateEmailStrict(email: string): EmailValidationResult {
  if (!email || typeof email !== 'string') {
    return {
      isValid: false,
      message: '邮箱地址不能为空',
      domain: null,
      localPart: null
    };
  }

  const trimmedEmail = email.trim();
  
  if (trimmedEmail === '') {
    return {
      isValid: false,
      message: '邮箱地址不能为空',
      domain: null,
      localPart: null
    };
  }

  if (!EMAIL_REGEX.STRICT.test(trimmedEmail)) {
    return {
      isValid: false,
      message: '邮箱格式不符合严格标准',
      domain: null,
      localPart: null
    };
  }

  const [localPart, domain] = trimmedEmail.split('@');
  
  // 检查本地部分长度
  if (localPart.length > 64) {
    return {
      isValid: false,
      message: '邮箱本地部分长度不能超过64个字符',
      domain: domain,
      localPart: localPart
    };
  }

  // 检查域名长度
  if (domain.length > 253) {
    return {
      isValid: false,
      message: '邮箱域名长度不能超过253个字符',
      domain: domain,
      localPart: localPart
    };
  }

  return {
    isValid: true,
    message: '邮箱格式符合严格标准',
    domain: domain,
    localPart: localPart
  };
}

/**
 * 检查邮箱是否为空
 * @param {string} email - 邮箱地址
 * @returns {boolean} 是否为空
 */
export function isEmptyEmail(email: string): boolean {
  return !email || typeof email !== 'string' || email.trim() === '';
}

/**
 * 检查是否为临时邮箱
 * @param {string} email - 邮箱地址
 * @returns {boolean} 是否为临时邮箱
 */
export function isTemporaryEmail(email: string): boolean {
  if (isEmptyEmail(email)) return false;
  
  const domain = email.split('@')[1];
  if (!domain) return false;
  
  return TEMPORARY_EMAIL_DOMAINS.some(tempDomain => 
    domain.toLowerCase().includes(tempDomain.toLowerCase())
  );
}

/**
 * 检查域名是否在白名单中
 * @param {string} email - 邮箱地址
 * @param {Array<string>} whitelist - 白名单域名数组
 * @returns {boolean} 是否在白名单中
 */
export function isDomainWhitelisted(email: string, whitelist: string[]): boolean {
  if (isEmptyEmail(email) || !Array.isArray(whitelist)) return false;
  
  const domain = email.split('@')[1];
  if (!domain) return false;
  
  return whitelist.some(allowedDomain => 
    domain.toLowerCase() === allowedDomain.toLowerCase()
  );
}

/**
 * 检查域名是否在黑名单中
 * @param {string} email - 邮箱地址
 * @param {Array<string>} blacklist - 黑名单域名数组
 * @returns {boolean} 是否在黑名单中
 */
export function isDomainBlacklisted(email: string, blacklist: string[]): boolean {
  if (isEmptyEmail(email) || !Array.isArray(blacklist)) return false;
  
  const domain = email.split('@')[1];
  if (!domain) return false;
  
  return blacklist.some(blockedDomain => 
    domain.toLowerCase() === blockedDomain.toLowerCase()
  );
}

/**
 * 批量邮箱校验
 * @param {Array<string>} emails - 邮箱数组
 * @param {BatchEmailValidationConfig} config - 配置选项
 * @returns {BatchEmailValidationResult} 批量校验结果
 */
export function validateBatchEmails(emails: string[], config: BatchEmailValidationConfig = {}): BatchEmailValidationResult {
  const {
    maxCount = 1000,
    minCount = 1,
    checkUnique = true,
    allowEmpty = false,
    strictMode = false,
    whitelist = [],
    blacklist = [],
    blockTemporary = false
  } = config;

  if (!Array.isArray(emails)) {
    return {
      isValid: false,
      message: '邮箱数组格式不正确',
      validEmails: [],
      invalidEmails: [],
      duplicateEmails: [],
      totalCount: 0,
      validCount: 0,
      invalidCount: 0,
      duplicateCount: 0,
      emptyCount: 0,
      exceededCount: 0
    };
  }

  const validEmails: string[] = [];
  const invalidEmails: Array<{ email: string; reason: string }> = [];
  const duplicateEmails: string[] = [];
  const seenEmails = new Set<string>();
  let emptyCount = 0;
  let exceededCount = 0;

  // 检查数量限制
  if (emails.length > maxCount) {
    exceededCount = emails.length - maxCount;
  }

  if (emails.length < minCount) {
    return {
      isValid: false,
      message: `邮箱数量不能少于${minCount}个`,
      validEmails: [],
      invalidEmails: [],
      duplicateEmails: [],
      totalCount: emails.length,
      validCount: 0,
      invalidCount: 0,
      duplicateCount: 0,
      emptyCount: 0,
      exceededCount: 0
    };
  }

  for (let i = 0; i < emails.length; i++) {
    const email = emails[i];
    
    // 检查空值
    if (isEmptyEmail(email)) {
      emptyCount++;
      if (!allowEmpty) {
        invalidEmails.push({
          email: email,
          reason: '邮箱地址不能为空'
        });
        continue;
      }
    }

    // 检查唯一性
    if (checkUnique && email && seenEmails.has(email.toLowerCase())) {
      duplicateEmails.push(email);
      continue;
    }

    // 校验邮箱格式
    const validationResult = strictMode ? validateEmailStrict(email) : validateEmail(email);
    
    if (!validationResult.isValid) {
      invalidEmails.push({
        email: email,
        reason: validationResult.message
      });
      continue;
    }

    // 检查白名单
    if (whitelist.length > 0 && !isDomainWhitelisted(email, whitelist)) {
      invalidEmails.push({
        email: email,
        reason: '域名不在白名单中'
      });
      continue;
    }

    // 检查黑名单
    if (blacklist.length > 0 && isDomainBlacklisted(email, blacklist)) {
      invalidEmails.push({
        email: email,
        reason: '域名在黑名单中'
      });
      continue;
    }

    // 检查临时邮箱
    if (blockTemporary && isTemporaryEmail(email)) {
      invalidEmails.push({
        email: email,
        reason: '不允许使用临时邮箱'
      });
      continue;
    }

    validEmails.push(email);
    if (checkUnique) {
      seenEmails.add(email.toLowerCase());
    }
  }

  const totalCount = emails.length;
  const validCount = validEmails.length;
  const invalidCount = invalidEmails.length;
  const duplicateCount = duplicateEmails.length;

  return {
    isValid: validCount > 0 && invalidCount === 0 && duplicateCount === 0,
    message: validCount > 0 ? '批量校验完成' : '没有有效的邮箱地址',
    validEmails,
    invalidEmails,
    duplicateEmails,
    totalCount,
    validCount,
    invalidCount,
    duplicateCount,
    emptyCount,
    exceededCount
  };
}

/**
 * 简化批量邮箱校验
 * @param {Array<string>} emails - 邮箱数组
 * @returns {BatchEmailValidationResult} 简化校验结果
 */
export function validateBatchEmailsSimple(emails: string[]): BatchEmailValidationResult {
  return validateBatchEmails(emails, {
    maxCount: 100,
    minCount: 1,
    checkUnique: true,
    allowEmpty: false,
    strictMode: false
  });
}

/**
 * 检查邮箱数量限制
 * @param {Array<string>} emails - 邮箱数组
 * @param {number} maxCount - 最大数量
 * @param {number} minCount - 最小数量
 * @returns {EmailCountLimitResult} 数量检查结果
 */
export function checkEmailCountLimit(emails: string[], maxCount: number = 100, minCount: number = 1): EmailCountLimitResult {
  if (!Array.isArray(emails)) {
    return {
      isValid: false,
      message: '邮箱数组格式不正确',
      totalCount: 0,
      exceededCount: 0,
      insufficientCount: 0
    };
  }

  const totalCount = emails.length;
  const exceededCount = Math.max(0, totalCount - maxCount);
  const insufficientCount = Math.max(0, minCount - totalCount);

  return {
    isValid: totalCount >= minCount && totalCount <= maxCount,
    message: totalCount < minCount ? 
      `邮箱数量不能少于${minCount}个` : 
      totalCount > maxCount ? 
      `邮箱数量不能超过${maxCount}个` : 
      '邮箱数量符合要求',
    totalCount,
    exceededCount,
    insufficientCount
  };
}

/**
 * 邮箱分页处理
 * @param {Array<string>} emails - 邮箱数组
 * @param {number} pageSize - 每页大小
 * @param {number} page - 页码（从1开始）
 * @returns {EmailPaginationResult} 分页结果
 */
export function paginateEmails(emails: string[], pageSize: number = 50, page: number = 1): EmailPaginationResult {
  if (!Array.isArray(emails)) {
    return {
      emails: [],
      totalCount: 0,
      pageSize: pageSize,
      currentPage: page,
      totalPages: 0,
      hasNext: false,
      hasPrev: false
    };
  }

  const totalCount = emails.length;
  const totalPages = Math.ceil(totalCount / pageSize);
  const currentPage = Math.max(1, Math.min(page, totalPages));
  const startIndex = (currentPage - 1) * pageSize;
  const endIndex = Math.min(startIndex + pageSize, totalCount);
  
  const pageEmails = emails.slice(startIndex, endIndex);

  return {
    emails: pageEmails,
    totalCount,
    pageSize,
    currentPage,
    totalPages,
    hasNext: currentPage < totalPages,
    hasPrev: currentPage > 1
  };
}

/**
 * 格式化邮箱
 * @param {string} email - 邮箱地址
 * @param {EmailFormatOptions} options - 格式化选项
 * @returns {string} 格式化后的邮箱
 */
export function formatEmail(email: string, options: EmailFormatOptions = {}): string {
  if (isEmptyEmail(email)) return '';

  const {
    toLowerCase = true,
    trim = true
  } = options;

  let formattedEmail = email;

  if (trim) {
    formattedEmail = formattedEmail.trim();
  }

  if (toLowerCase) {
    formattedEmail = formattedEmail.toLowerCase();
  }

  return formattedEmail;
}

/**
 * 邮箱脱敏
 * @param {string} email - 邮箱地址
 * @param {EmailMaskOptions} options - 脱敏选项
 * @returns {string} 脱敏后的邮箱
 */
export function maskEmail(email: string, options: EmailMaskOptions = {}): string {
  if (isEmptyEmail(email)) return '';

  const {
    maskChar = '*',
    showFirst = 2,
    showLast = 2
  } = options;

  const [localPart, domain] = email.split('@');
  
  if (!localPart || !domain) return email;

  const localLength = localPart.length;
  const domainLength = domain.length;

  let maskedLocal = localPart;
  let maskedDomain = domain;

  // 脱敏本地部分
  if (localLength > showFirst + showLast) {
    const middleLength = localLength - showFirst - showLast;
    const middle = maskChar.repeat(middleLength);
    maskedLocal = localPart.substring(0, showFirst) + middle + localPart.substring(localLength - showLast);
  }

  // 脱敏域名部分
  if (domainLength > showFirst + showLast) {
    const middleLength = domainLength - showFirst - showLast;
    const middle = maskChar.repeat(middleLength);
    maskedDomain = domain.substring(0, showFirst) + middle + domain.substring(domainLength - showLast);
  }

  return `${maskedLocal}@${maskedDomain}`;
}

/**
 * 提取邮箱域名
 * @param {string} email - 邮箱地址
 * @returns {string} 域名
 */
export function extractDomain(email: string): string {
  if (isEmptyEmail(email)) return '';
  
  const parts = email.split('@');
  return parts.length > 1 ? parts[1] : '';
}

/**
 * 提取邮箱本地部分
 * @param {string} email - 邮箱地址
 * @returns {string} 本地部分
 */
export function extractLocalPart(email: string): string {
  if (isEmptyEmail(email)) return '';
  
  const parts = email.split('@');
  return parts.length > 0 ? parts[0] : '';
}

/**
 * 提取唯一邮箱
 * @param {Array<string>} emails - 邮箱数组
 * @returns {Array<string>} 唯一邮箱数组
 */
export function extractUniqueEmails(emails: string[]): string[] {
  if (!Array.isArray(emails)) return [];
  
  const uniqueEmails = new Set<string>();
  
  emails.forEach(email => {
    if (!isEmptyEmail(email)) {
      uniqueEmails.add(email.toLowerCase().trim());
    }
  });
  
  return Array.from(uniqueEmails);
}

/**
 * 邮箱分页处理（带校验）
 * @param {Array<string>} emails - 邮箱数组
 * @param {number} pageSize - 每页大小
 * @param {number} page - 页码
 * @param {BatchEmailValidationConfig} config - 校验配置
 * @returns {EmailPaginationWithValidationResult} 分页校验结果
 */
export function paginateEmailsWithValidation(
  emails: string[], 
  pageSize: number = 50, 
  page: number = 1, 
  config: BatchEmailValidationConfig = {}
): EmailPaginationWithValidationResult {
  const paginationResult = paginateEmails(emails, pageSize, page);
  
  if (paginationResult.emails.length === 0) {
    return {
      ...paginationResult,
      validationResult: {
        isValid: true,
        message: '没有邮箱需要校验',
        validEmails: [],
        invalidEmails: [],
        duplicateEmails: [],
        totalCount: 0,
        validCount: 0,
        invalidCount: 0,
        duplicateCount: 0,
        emptyCount: 0,
        exceededCount: 0
      }
    };
  }

  const validationResult = validateBatchEmails(paginationResult.emails, config);
  
  return {
    ...paginationResult,
    validationResult
  };
}